package cn.ac.iscas.controller;

import cn.ac.iscas.domain.job.*;
import cn.ac.iscas.domain.response.AnalyzeColumResponse;
import cn.ac.iscas.domain.response.job.JobSearchResponse;
import cn.ac.iscas.domain.response.middleplatform.ResponseEntity;
import cn.ac.iscas.service.flink.SqlJobService;
import cn.ac.iscas.service.flink.LogService;
import com.iscas.datasong.lib.common.DataSongException;
import com.iscas.datasong.lib.common.Status;
import com.iscas.datasong.lib.util.DataSongExceptionUtils;
import com.iscas.datasong.lib.util.DataSongStringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/*
* 任务控制层
*/
//@CrossOrigin
@RestController
@ResponseBody
//@RequestMapping("/etl/job")
@RequestMapping("/job")
public class JobController {

	@Autowired
	SqlJobService sqlJobService;

	@Autowired
	private LogService logService;

	/**
	 * 查询任务列表 post
	 *
	 * @param jobSearch 查询条件
	 * @return 返回结果
	 */
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	public ResponseEntity searchJob(@RequestBody JobSearch jobSearch) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity<JobSearchResponse>(Status.OK.getValue(),"search job info ok");

		try{
			JobSearchResponse response = sqlJobService.searchJob(jobSearch);
			responseEntity.setData(response);
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取任务列表！",e);
		}

		return responseEntity;
	}

	@RequestMapping(value = "/all", method = RequestMethod.GET)
	//@ApiOperation(value = "【获取所有任务名】", notes = "用于下拉列表")
	public ResponseEntity getAllJob( ) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity<JobSearchResponse>(Status.OK.getValue(),"get all job ok");

		try{
			Map<String, String> response = sqlJobService.getAllJob();
			responseEntity.setData(response );
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取任务列表！",e);
		}

		return responseEntity;
	}

	/**
	 * 根据id删除任务 delete
	 *
	 * @param id 任务唯一id
	 * @return 返回结果
	 */
	
	@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
	//@ApiOperation(value = "【删除任务】", notes = "如果删除多条任务，用英文逗号分隔")
	public ResponseEntity deleteJob(@PathVariable String id) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"delete success");
		try{
			if(DataSongStringUtils.isEmpty(id)){
				throw  new DataSongException(Status.PARAM_ERROR,"the param id can not be empty!");
			}

			if(id.contains(",")) {
				List ids = Arrays.asList(id.split(","));
				if (sqlJobService.deleteJob(ids)) {
					responseEntity.setData(id);
				} else {
					responseEntity.setData("批量删除任务失败！");
				}
			}else {
				if (sqlJobService.deleteJob(id)) {
					responseEntity.setData(id);
				} else {
					responseEntity.setData("删除任务失败！");
				}
			}
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("删除任务！",e);
		}
		return responseEntity;
	}

	/**
	 * 根据id号获取一个job的详情，用于编辑/复制等 get
	 *
	 * @param id 任务唯一id
	 * @return
	 */
	
	@RequestMapping(value = "/job/{id}", method = RequestMethod.GET)
	//@ApiOperation(value = "【获取任务详情】", notes = "根据id号获取任务的详情")
	public ResponseEntity getJob(@PathVariable String id) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"获取任务详情成功！");
		try{
			Job jobMetadata = sqlJobService.getJob(id);
			responseEntity.setData(jobMetadata);
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取任务详情！",e);
		}
		return responseEntity;
	}

	/**
	 * 任务校验 post
	 * @param job
	 * @return
	 */
	
	@RequestMapping(value = "/validate", method = RequestMethod.POST)
	//@ApiOperation(value = "【校验任务正确性】", notes = "逐一判断任务中每个组件的基本正确性，校验失败会返回失败原因，可直接提示给用户")
	public ResponseEntity validateJob(@RequestBody Job job) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"validate success");
		try{
			if(sqlJobService.validateJob(job)){
				responseEntity.setData(job);
				responseEntity.setMessage("校验成功");
			}
			else{
				responseEntity.setMessage("校验失败");
			}
		}catch (DataSongException e){
			e.printStackTrace();

			throw e;
		}catch (Exception e){
			e.printStackTrace();

			throw new DataSongException("校验异常！",e);
		}
		return responseEntity;
	}

	/**
	 * 任务执行 post
	 *
	 * @param job
	 * @return
	 */
	
	@RequestMapping(value = "/execute", method = RequestMethod.POST)
	//@ApiOperation(value = "【执行任务】", notes = "先检验job，查看是否已经保存过，保存过取已有状态验证，验证通过保存新任务，保存完成启动执行")

	//todo:区分任务类型
	public ResponseEntity executeJob(@RequestBody Job job) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"execute success");
		String jobId = null;
		try{
			jobId = sqlJobService.executeJob(job);
  			if(DataSongStringUtils.isNotEmpty(job)){
				responseEntity.setMessage("执行成功");
			}
			else{
				responseEntity.setMessage("执行失败");
			}
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("执行任务异常！",e);
		}finally {
			responseEntity.setData(jobId); //已经生成id必须返给前台，避免重复执行生成多条
		}
		return responseEntity;
	}

	/**
	 * 任务执行 post
	 *
	 * @param jobIds
	 * @return
	 */
	@RequestMapping(value = "/batch/execute", method = RequestMethod.POST)
	//@ApiOperation(value = "【批量执行任务】", notes = "根据id启动执行任务")
	public ResponseEntity executeJob(@RequestBody List<String> jobIds) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"batch execute success");
		try{
			if(sqlJobService.executeJob(jobIds)){
				responseEntity.setData(jobIds);
				responseEntity.setMessage("执行成功");
			}else{
				responseEntity.setMessage("执行失败");
			}
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("执行异常！",e);
		}
		return responseEntity;
	}

	/**
	 * 任务停止 post
	 *
	 * @param jobIds
	 * @return
	 */
	@RequestMapping(value = "/stop", method = RequestMethod.POST)
	//@ApiOperation(value = "【终止任务】", notes = "根据id启动执行任务，支持单个和批量")
	public ResponseEntity stopJob(@RequestBody List<String> jobIds) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"stop success");
		try{
			if(sqlJobService.stopJob(jobIds)){
				responseEntity.setData(jobIds);
				responseEntity.setMessage("终止任务成功");
			}else{
				responseEntity.setMessage("终止任务失败");
			}
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("终止任务异常！",e);
		}
		return responseEntity;
	}

	/**
	 * 任务保存 post
	 *
	 * @param job
	 * @return
	 */
	
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	//@ApiOperation(value = "【保存任务】", notes = "如果已经保存过，先判断任务状态，通过后保存，不校验正确性，方便存草稿")
	public ResponseEntity saveJob(@RequestBody Job job) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"Save job success");
		try{
			String _id = sqlJobService.saveJob(job);
			if (_id == null) {
				responseEntity.setStatus(Status.SERVER_ERROR.getValue());
				responseEntity.setMessage("Save job failed!");
			}
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("保存任务异常！",e);
		}
		return responseEntity;
	}

	/**
	 * 任务保存 post
	 *
	 * @param jobs
	 * @return
	 */
	@RequestMapping(value = "/batch/save", method = RequestMethod.POST)
	//@ApiOperation(value = "【批量保存任务】", notes = "用于批量导入，唯一id重新生成")
	public ResponseEntity saveJob(@RequestBody List<Job> jobs) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"save success");

			List<String> ids = sqlJobService.saveJob(jobs);
			if(ids != null && ids.size() == jobs.size()){
				responseEntity.setData(ids);
				responseEntity.setMessage("保存成功");
			}
			else{
				responseEntity.setMessage("保存失败");
			}

		return responseEntity;
	}

	/**
	 * 任务清空
	 *
	 * @param id
	 * @return
	 */
	
	@RequestMapping(value = "/clear/{id}", method = RequestMethod.POST)
	//@ApiOperation(value = "【清空任务】", notes = "其实可以废弃，直接保存空任务")
	public ResponseEntity clearJob(@PathVariable String id) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"clear job successfully");
		try{
			String _id = sqlJobService.clearJob(id);
			if(!_id.isEmpty()){
				responseEntity.setData(_id);
				responseEntity.setMessage("清空成功");
			}
			else{
				responseEntity.setMessage("清空失败");
			}
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("清空任务异常！",e);
		}
		return responseEntity;
	}

//	/**
//	 * 取初始列字段名
//	 * @param job
//	 * @return
//	 */
//	
//	@RequestMapping(value = "/column", method = RequestMethod.POST)
//	//@ApiOperation(value = "【获取输入源的初始列】", notes = "获取输入源组件的输入列和样例数据，最好前台能将返回的表头，放到job中")
//	public ResponseEntity analyzeInitialColumn(@RequestBody Job job) throws DataSongException {
//		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"Analyze reader component init column successfully!");
//		try{
//			AnalyzeColumResponse readerColumResponse = flinkSqlJobService.analyzeInitialColumn(job);
//			responseEntity.setData(readerColumResponse);
//		}catch (DataSongException e){
//			e.printStackTrace();
//			throw e;
//		}catch (Exception e){
//			e.printStackTrace();
//			throw new DataSongException("获取输入源的初始列异常！",e);
//		}
//		return responseEntity;
//	}


	/**
	 * 获取组件数据输入列
	 *
	 * @param job
	 * @param cId 组件id
	 * @return
	 */
	
	@RequestMapping(value = "/column/{cId}", method = RequestMethod.POST)
	//@ApiOperation(value = "【获取组件的输入列】", notes = "有个问题，不返回job，输入源的列没法保存，每次重新获取效率低？？？")
	public ResponseEntity analyzeComponentColumn( @PathVariable String cId,@RequestBody Job job) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"Analyze component input column successfully!");
		try {
			AnalyzeColumResponse analyzeColumResponse = sqlJobService.analyzeComponentColumn(job, cId);
			responseEntity.setData(analyzeColumResponse);
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取中间组件的输入列异常！",e);
		}
		return responseEntity;
	}

	/**
	 * 获取任务执行的日志输出
	 *
	 * @param id
	 * @return
	 */
	
	@RequestMapping(value = "/log/{id}", method = RequestMethod.GET)
	public ResponseEntity getJobLog(@PathVariable String id) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"save success");
		try{
			List<JobLog> jobLogs = sqlJobService.getJobLog(id);
			responseEntity.setData(jobLogs);
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取日志异常！",e);
		}
		return responseEntity;
	}


	@RequestMapping(value = "/log/", method = RequestMethod.POST)
	public ResponseEntity getJobLog(@RequestBody String[] id) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"log fetched!");
		try{
			String jobLogs = logService.getJobLog(id[0], id[1]);
			responseEntity.setData(jobLogs);
		} catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取日志异常！",e);
		}
		return responseEntity;
	}

	/**
	 * 更新任务状态
	 *
	 * @param id
	 * @param status
	 * @return
	 */

	@RequestMapping(value = "job/status/{id}", method = RequestMethod.POST)
	public ResponseEntity updateJobStatus(@PathVariable String id, @RequestBody JobStatus status) {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"update status success");
		try{
			boolean ret = sqlJobService.updateJobStatus(id, status);
			if(ret){
				responseEntity.setData(ret);
			}
			else{
				responseEntity.setData("update status failed");
			}
		}catch (Exception e){
			e.printStackTrace();
			responseEntity.setStatus(Status.SERVER_ERROR.getValue());
			responseEntity.setMessage(DataSongExceptionUtils.getExceptionInfo(e));
		}
		return responseEntity;
	}

	@RequestMapping(value = "/column/type", method = RequestMethod.GET)
	//@ApiOperation(value = "【获取列的类型】", notes = "获取列的类型")
	public ResponseEntity getColumnType( ) throws DataSongException {
		ResponseEntity responseEntity = new ResponseEntity(Status.OK.getValue(),"获取成功！");
		try {
			responseEntity.setData(sqlJobService.getColumnType());
		}catch (DataSongException e){
			e.printStackTrace();
			throw e;
		}catch (Exception e){
			e.printStackTrace();
			throw new DataSongException("获取列的类型异常！",e);
		}

		return responseEntity;
	}
}
